import 'implementation/ALDownloaderIMP.dart';
import 'ALDownloaderHandlerInterface.dart';
import 'ALDownloaderStatus.dart';
import 'ALDownloaderTask.dart';
import 'ALDownloaderTypeDefine.dart';

/// ALDownloader
abstract class ALDownloader {
  /// Initialize
  ///
  /// It must be called first.
  static void initialize() => ALDownloaderIMP.initialize();

  /// Configure print
  ///
  /// **parameters**
  ///
  /// [enabled] set whether enable print
  ///
  /// [frequentEnabled] set whether enable frequent print
  ///
  /// **discussion**
  ///
  /// Printing before calling this function applys the default. Default is false.
  static void configurePrint(bool enabled, {bool frequentEnabled = false}) =>
      ALDownloaderIMP.configurePrint(enabled, frequentEnabled: frequentEnabled);

  /// Download
  ///
  /// **parameters**
  ///
  /// [url] url
  ///
  /// [handlerInterface] handler interface
  ///
  /// It is an one-off interface which will be destroyed when the download succeeded/failed.
  ///
  /// [directoryPath], [fileName]
  ///
  /// If any one of them is `null`, both of them are invalid. At this time, [ALDownloader] will
  /// generate default.
  ///
  /// [headers] download http header
  ///
  /// [redownloadIfNeeded]
  ///
  /// If [redownloadIfNeeded] is `true` and any one of [directoryPath], [fileName], [headers] content
  /// is changed than before, [url] will re-download. Otherwise, [url] will not re-download.
  ///
  /// **return**
  ///
  /// [ALDownloaderHandlerInterfaceId] handler interface id
  ///
  /// It is used for managing handler interface.
  static ALDownloaderHandlerInterfaceId? download(String url,
          {String? directoryPath,
          String? fileName,
          Map<String, String>? headers,
          bool redownloadIfNeeded = false,
          ALDownloaderHandlerInterface? handlerInterface}) =>
      ALDownloaderIMP.download(url,
          directoryPath: directoryPath,
          fileName: fileName,
          headers: headers,
          redownloadIfNeeded: redownloadIfNeeded,
          handlerInterface: handlerInterface);

  /// Add a handler interface
  ///
  /// **parameters**
  ///
  /// [handlerInterface] handler interface
  ///
  /// It is an one-off interface which will be destroyed when the download succeeded/failed.
  ///
  /// [url] url
  ///
  /// **return**
  ///
  /// [ALDownloaderHandlerInterfaceId] handler interface id
  ///
  /// It is used for managing handler interface.
  static ALDownloaderHandlerInterfaceId addHandlerInterface(
          ALDownloaderHandlerInterface handlerInterface, String url) =>
      ALDownloaderIMP.addHandlerInterface(handlerInterface, url);

  /// Add a forever handler interface
  ///
  /// **parameters**
  ///
  /// [handlerInterface] handler interface
  ///
  /// It is a forever interface which never is destroyed unless the fllowing function is called.
  ///
  /// [removeHandlerInterfaceForUrl], [removeHandlerInterfaceForId], [removeHandlerInterfaceForAll]
  ///
  /// [url] url
  ///
  /// **return**
  ///
  /// [ALDownloaderHandlerInterfaceId] handler interface id
  ///
  /// It is used for managing handler interface.
  static ALDownloaderHandlerInterfaceId addForeverHandlerInterface(
          ALDownloaderHandlerInterface handlerInterface, String url) =>
      ALDownloaderIMP.addForeverHandlerInterface(handlerInterface, url);

  /// Remove handler interface
  ///
  /// **parameters**
  ///
  /// [url] url
  static void removeHandlerInterfaceForUrl(String url) =>
      ALDownloaderIMP.removeHandlerInterfaceForUrl(url);

  /// Remove handler interface
  ///
  /// **parameters**
  ///
  /// [id] handler interface id
  ///
  /// It is generated by [download], [addHandlerInterface], [addForeverHandlerInterface].
  static void removeHandlerInterfaceForId(ALDownloaderHandlerInterfaceId id) =>
      ALDownloaderIMP.removeHandlerInterfaceForId(id);

  /// Remove all handler interfaces
  static void removeHandlerInterfaceForAll() =>
      ALDownloaderIMP.removeHandlerInterfaceForAll();

  /// Get download status
  ///
  /// **parameters**
  ///
  /// [url] url
  ///
  /// **return**
  ///
  /// [ALDownloaderStatus] status
  static Future<ALDownloaderStatus> getStatusForUrl(String url) =>
      ALDownloaderIMP.getStatusForUrl(url);

  /// Get download progress
  ///
  /// **parameters**
  ///
  /// [url] url
  ///
  /// **return**
  ///
  /// [double] progress
  static Future<double> getProgressForUrl(String url) =>
      ALDownloaderIMP.getProgressForUrl(url);

  /// Get task
  ///
  /// **parameters**
  ///
  /// [url] url
  ///
  /// **return**
  ///
  /// [ALDownloaderTask] task
  static Future<ALDownloaderTask?> getTaskForUrl(String url) =>
      ALDownloaderIMP.getTaskForUrl(url);

  /// Get all tasks
  ///
  /// **return**
  ///
  /// [List<ALDownloaderTask>] tasks
  static Future<List<ALDownloaderTask>> get tasks => ALDownloaderIMP.tasks;

  /// Pause download
  ///
  /// Stop download, but the incomplete data will not be deleted.
  ///
  /// **parameters**
  ///
  /// [url] url
  static void pause(String url) => ALDownloaderIMP.pause(url);

  /// Pause all downloads
  ///
  /// This is a multiple of [pause], see [pause].
  static void pauseAll() => ALDownloaderIMP.pauseAll();

  /// Cancel download
  ///
  /// Stop download, and the incomplete data will be deleted.
  ///
  /// **parameters**
  ///
  /// [url] url
  static void cancel(String url) => ALDownloaderIMP.cancel(url);

  /// Cancel all downloads
  ///
  /// This is a multiple of [cancel], see [cancel].
  static void cancelAll() => ALDownloaderIMP.cancelAll();

  /// Remove download
  ///
  /// Remove download, and all the data will be deleted.
  ///
  /// **parameters**
  ///
  /// [url] url
  static void remove(String url) => ALDownloaderIMP.remove(url);

  /// Remove all downloads
  ///
  /// This is a multiple of [remove], see [remove].
  static void removeAll() => ALDownloaderIMP.removeAll();

  /// Privatize constructor
  ALDownloader._();
}
